package main

import (
	"gomicro-sharemod/services/user-service/handler"
	"gomicro-sharemod/services/user-service/middlewares"
	"gomicro-sharemod/services/user-service/tools"

	log "go-micro.dev/v5/logger"

	pbUser "gomicro-sharemod/services/user-service/proto/user"

	"github.com/hashicorp/consul/api"
	"github.com/micro/plugins/v5/registry/consul"
	"github.com/micro/plugins/v5/registry/etcd"
	"github.com/micro/plugins/v5/registry/nacos"
	trace_opentracing "github.com/micro/plugins/v5/wrapper/trace/opentracing"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/urfave/cli/v2"
	"go-micro.dev/v5"
	"go-micro.dev/v5/registry"
)

// 编译windows版: go build -o user-service.exe main.go
// 编译linux版: go build -o user-service main.go
func main() {
	// 初始化Zap日志
	zapLogger := tools.InitZapLogger(tools.ServiceName)
	defer zapLogger.Sync()

	// 创建gRPC日志适配器
	grpcLogger := &tools.ZapGrpcLogger{
		Logger: zapLogger.Sugar(),
	}

	// 替换所有内部日志系统
	tools.ReplaceMicroLoggers(zapLogger, grpcLogger)

	var registryInstance registry.Registry
	// 获取consul、nacos、etcd配置信息
	config, err := tools.GetConfig(tools.ServiceRegistry, "yml")
	if err != nil {
		log.Fatalf("获取"+tools.ServiceRegistry+"配置信息错误: %v", err)
	}

	// ----------------- 服务注册开始 -----------------
	switch tools.ServiceRegistry {
	case "etcd":
		//集成 etcd
		registryInstance = etcd.NewRegistry(func(op *registry.Options) {
			//地址
			op.Addrs = config.GetStringSlice(tools.Env + ".addrs")
			//密码
			// etcd.Auth("gangan", "123")
		}, etcd.Auth(config.GetString(tools.Env+".username"), config.GetString(tools.Env+".password")))

	case "consul":
		// 集成consul
		registryInstance = consul.NewRegistry(
			registry.Addrs(config.GetString(tools.Env+".addrs")),
			consul.Config(&api.Config{
				Token: config.GetString(tools.Env + ".secret_id"),
			}),
		)

	case "nacos":
		//集成 nacos
		registryInstance = nacos.NewRegistry(func(op *registry.Options) {
			op.Addrs = config.GetStringSlice(tools.Env + ".addrs")
		}, nacos.WithClientConfig(constant.ClientConfig{
			NamespaceId: config.GetString(tools.Env + ".name_space_id"),
			Username:    config.GetString(tools.Env + ".username"),
			Password:    config.GetString(tools.Env + ".password"),
		}))
	}
	// ----------------- 服务注册结束 -----------------

	// 获取日志实例
	tools.Zaplog = log.DefaultLogger

	// ---------- 初始化 jaeger tracer 开始 -----------
	tracer, closer, err := tools.NewTracer(tools.ServiceName, tools.JaegerAgentURL)
	if err != nil {
		tools.Zaplog.Log(log.FatalLevel, "初始化 jaeger tracer错误: ", err)
	}
	defer closer.Close()
	// ---------- 初始化 jaeger tracer 结束 -----------

	// 在 Go-Micro v5 中同时创建 gRPC 服务器和 Go Micro 服务的模式，结合了两者的优势：
	// gRPC 服务器：提供高性能、低延迟的核心通信能力
	// Go Micro 服务：提供完整的微服务治理生态系统
	// 这种架构特别适合需要与 DTM 等分布式事务框架集成的场景：
	// 直接 gRPC 通信确保与 DTM 兼容
	// 服务治理能力保障系统可靠性
	// 中间件支持增强可观测性和容错能力

	// 创建原生 gRPC 服务器
	// grpcServer := microGrpc.NewServer(
	// 	server.Address(tools.ServiceHost + ":" + tools.ServicePort),
	// )

	// 创建微服务
	srv := micro.NewService(
		micro.Address(tools.ServiceHost+":"+tools.ServicePort),
		micro.Name(tools.ServiceName),
		micro.Version(tools.ServiceVersion),
		micro.Registry(registryInstance),
		micro.Flags(&cli.StringFlag{
			Name:  "env",
			Usage: "The environment",
			Value: "dev",
		}),
		// micro.WrapHandler(
		// 	limiter.NewHandlerWrapper(ratelimit.NewBucketWithRate(float64(tools.Qps), int64(tools.Qps)), false),
		// 	prometheus.NewHandlerWrapper(
		// 		prometheus.ServiceName(tools.ServiceName),
		// 		prometheus.ServiceVersion(tools.ServiceVersion),
		// 	),
		// ),

		// 这是关键：在服务创建时设置日志器
		micro.Logger(log.DefaultLogger),

		// 注册日志中间件
		micro.WrapHandler(middlewares.ZapLogWrapper(zapLogger)),

		// 注册追踪处理器
		micro.WrapHandler(trace_opentracing.NewHandlerWrapper(tracer)),
	)

	// 初始化微服务
	srv.Init()

	// 注册用户处理
	pbUser.RegisterUserServiceHandler(srv.Server(), new(handler.UserHandler))

	// 运行服务
	if err := srv.Run(); err != nil {
		tools.Zaplog.Log(log.ErrorLevel, "运行服务失败："+err.Error())
	}
}
